﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using ZK.Models;

namespace ZK.HardWareBLL
{
    /// <summary>
    /// 煤管票
    /// </summary>
    public class CMTBLL
    {

        string CMTInIp;
        static string CMTOutIp = Common.AppConfigHelper.GetAppSettings("CMTOutIp");
        static string CMTMCNum = Common.AppConfigHelper.GetAppSettings("CMTMCNum");


        //public CMTBLL()
        //{
        //    CMTInIp = Common.AppConfigHelper.GetAppSettings("CMTInIp");
        //    CMTOutIp = Common.AppConfigHelper.GetAppSettings("CMTOutIp");
        //}

        private static CMTBLL cMT;
        public static CMTBLL GetInstance()
        {
            if (cMT == null)
            {
                cMT = new CMTBLL();
            }
            return cMT;
        }

        /// <summary>
        /// 煤管票-old
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public static bool SendOld(CMTM.OldM m)
        {
            try
            {
                StringBuilder sendStr = new StringBuilder();
                sendStr.Append(!string.IsNullOrEmpty(m.mSort) ? m.mSort : " ");
                sendStr.Append(",");
                sendStr.Append(!string.IsNullOrEmpty(m.mType) ? m.mType : " ");
                sendStr.Append(",");
                sendStr.Append(m.mGr);
                sendStr.Append(",");
                sendStr.Append(m.mTare);
                sendStr.Append(",");
                sendStr.Append(!string.IsNullOrEmpty(m.mCNumber) ? m.mCNumber : " ");
                sendStr.Append(",");
                sendStr.Append(!string.IsNullOrEmpty(m.mCtype) ? m.mCtype : " ");
                sendStr.Append(",");
                sendStr.Append(!string.IsNullOrEmpty(m.mCname) ? m.mCname : " ");
                sendStr.Append(",");
                sendStr.Append(!string.IsNullOrEmpty(m.mTarget) ? m.mTarget : " ");
                sendStr.Append(",");
                sendStr.Append(1);

                string ip = CMTOutIp;
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ip), 2000);
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Connect(remoteEP);
                //string sendStr = "块煤,三八块,48,15,陕K11111,前四后八,小王,山西,1";
                byte[] sendB = Encoding.GetEncoding("GB2312").GetBytes(sendStr.ToString());
                socket.Send(sendB);
                byte[] receiveData = new byte[100];
                int resNum = socket.Receive(receiveData);
                socket.Send(Encoding.GetEncoding("GB2312").GetBytes("END"));
                string receiveStr = Encoding.GetEncoding("GB2312").GetString(receiveData, 0, resNum);
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                string[] arr = receiveStr.Split(',');
                return arr[0] == "1" ? true : false;

            }
            catch (Exception ex)
            {
                Common.Log4.LogManage.WriteErr(ex.ToString());
                return false;
            }
        }


        /// <summary>
        /// 除皮
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public static Models.CMTM.CPReceiveM SendCP(Models.CMTM.CpSendMM m)
        {
            try
            {
                string ip = CMTOutIp;
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ip), 35580);
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Connect(remoteEP);
                string DataStr = Newtonsoft.Json.JsonConvert.SerializeObject(m);
                CMTM.SendM data = new CMTM.SendM()
                {
                    DataType = 1,
                    Data = DataStr

                };
                byte[] tosend = MakeApiFrame(data, CMTMCNum);
                socket.Send(tosend);
                byte[] receiveData = new byte[128];
                int resNum = socket.Receive(receiveData);
                byte[] lenx = { receiveData[3], receiveData[4], 0, 0 };
                int lenxInt = BitConverter.ToInt32(lenx, 0);
                int dataxInt = lenxInt - 26;
                receiveData = receiveData.Skip(15).Take(dataxInt).ToArray();
                string data1 = Encoding.GetEncoding("utf-8").GetString(receiveData);
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                Common.Log4.LogManage.WriteDebug("煤管票除皮返回数据：" + data1);
                var resM = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.CMTM.CPReceiveM>(data1);
                return resM;

            }
            catch (Exception ex)
            {
                Common.Log4.LogManage.WriteErr(ex.ToString());
                return new Models.CMTM.CPReceiveM();
            }
        }

        /// <summary>
        /// 称重
        /// </summary>
        /// <param name="ticket"></param>
        public static Models.CMTM.CPReceiveM SendWCXS(Models.CMTM.WCXSSendM m)
        {

            try
            {
                string ip = CMTOutIp;
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ip), 35580);
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Connect(remoteEP);
                string DataStr = Newtonsoft.Json.JsonConvert.SerializeObject(m);
                CMTM.SendM data = new CMTM.SendM()
                {
                    DataType = 3,
                    Data = DataStr

                };
                byte[] tosend = MakeApiFrame(data, CMTMCNum);
                socket.Send(tosend);
                byte[] receiveData = new byte[128];
                int resNum = socket.Receive(receiveData);
                byte[] lenx = { receiveData[3], receiveData[4], 0, 0 };
                int lenxInt = BitConverter.ToInt32(lenx, 0);
                int dataxInt = lenxInt - 26;
                receiveData = receiveData.Skip(15).Take(dataxInt).ToArray();
                string data1 = Encoding.GetEncoding("utf-8").GetString(receiveData);
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                Common.Log4.LogManage.WriteDebug("煤管票称重返回数据：" + data1);
                var resM = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.CMTM.CPReceiveM>(data1);
                return resM;
            }
            catch (Exception ex)
            {
                Common.Log4.LogManage.WriteErr(ex.ToString());
                return new Models.CMTM.CPReceiveM();
            }
        }

        private static byte[] MakeApiFrame(CMTM.SendM data, string pid)
        {
            byte[] dataBuff = Encoding.UTF8.GetBytes(data.Data);
            ushort bodyLen = (ushort)(10 + dataBuff.Length + 16);
            byte[] rst = new byte[ProtocolHead.Length + 2 + (int)bodyLen + ProtocolTail.Length];
            int idx = 0;
            Buffer.BlockCopy(ProtocolHead, 0, rst, 0, ProtocolHead.Length);
            idx += ProtocolHead.Length;
            Buffer.BlockCopy(BitConverter.GetBytes(bodyLen), 0, rst, idx, 2);
            idx += 2;
            Buffer.BlockCopy(BitConverter.GetBytes(DateTimeToUnixTimestamp(DateTime.Now)), 0, rst, idx, 8);
            idx += 8;
            Buffer.BlockCopy(BitConverter.GetBytes(data.DataType), 0, rst, idx, 2);
            idx += 2;
            Buffer.BlockCopy(dataBuff, 0, rst, idx, dataBuff.Length);
            idx += dataBuff.Length;
            byte[] toDigest = new byte[(int)(bodyLen - 16 + 5)];
            Buffer.BlockCopy(rst, ProtocolHead.Length + 2, toDigest, 0, (int)(bodyLen - 16));
            Buffer.BlockCopy(Encoding.ASCII.GetBytes(pid), 0, toDigest, (int)(bodyLen - 16), 5);
            Buffer.BlockCopy(md5.ComputeHash(toDigest), 0, rst, idx, 16);
            idx += 16;
            Buffer.BlockCopy(ProtocolTail, 0, rst, idx, ProtocolTail.Length);
            return rst;
        }
        private static readonly byte[] ProtocolHead = new byte[]
        {
            2,
            2,
            2
        };
        private static readonly byte[] ProtocolTail = new byte[]
        {
            3,
            3,
            3
        };
        public static ulong DateTimeToUnixTimestamp(DateTime dateTime)
        {
            return (ulong)(TimeZoneInfo.ConvertTimeToUtc(dateTime) - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
        }
        private static MD5 md5 = new MD5CryptoServiceProvider();
    }
}
